package uk.co.creacog.ccglib.flex.controls.soundviz
{
	import flash.display.LineScaleMode;
	import flash.display.Sprite;
	import flash.utils.ByteArray;
	
	import mx.logging.ILogger;
	import mx.logging.Log;
/*
The MIT License

Copyright (c) 2009 creative-cognition ltd

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

/**
 * <p>
 * WaveSprite
 * </p><p>
 * Simple sprite responsible for drawing a single channel of a sound wave
 * Built as a child DisplayObject of SimpleOscilloscope.
 * </p><p>
 * Released under The MIT License by creative-cognition ltd<br/>
 * <a href="http://www.creative-cognition.co.uk/">http://www.creative-cognition.co.uk/</a><br/>
 * <a href="http://blog.creacog.co.uk/">http://blog.creacog.co.uk/</a>
 * </p>
 * @see uk.co.creacog.lib.flex.controls.soundviz.SimpleOscilloscope
 */
	public class WaveSprite extends Sprite
	{
		private static const LOGGER:ILogger = Log.getLogger( "uk.co.creacog.lib.simpleoscilloscope.WaveSprite" );
		
		// draw modes
		public static const DRAW_LINE_ONLY	:String = "drawLineOnly";
		public static const DRAW_FILLED		:String = "drawFilled";

		// override width and height - we don't want any scaling going on
		private var _width	:Number;
		private var _height	:Number;

		private var _waveColour		:uint = 0xFFFFFF;
		private var _waveThickness	:uint = 1;
		
		private var _drawMode		:String = DRAW_LINE_ONLY;
		
		public function WaveSprite()
		{
			super();
		}
/**
 * <p>
 * Draw a wave from the supplied ByteArray. Note the ByteArray is expected to contain 
 * 1024 bytes representing 256 values of one channel of sound wave data generated from
 * SoundMixer.
 * </p>
 * @see flash.media.SoundMixer.computeSpectrum
 */		
		public function drawWave( ba:ByteArray ):void
		{
			var plotYAxis		:Number = Math.floor( _height / 2.0 );
			var plotXStep		:Number = ( _width - _waveThickness ) / 256;
			var halfThickness	:Number = _waveThickness / 2.0;

			graphics.clear();
			
			graphics.lineStyle( _waveThickness, _waveColour, 1, false, LineScaleMode.NONE );
			
			graphics.moveTo( halfThickness, plotYAxis );
			
			if( ba )
			{
				var soundValue:Number;
				
				ba.position = 0;
				
				//MOVE TO THE FIRST POINT
				soundValue = -ba.readFloat()*plotYAxis + plotYAxis;
				
				if( _drawMode == DRAW_FILLED )
				{
					graphics.beginFill( _waveColour, 1 );

					graphics.lineTo( halfThickness, soundValue);
				}
				else
				{
					graphics.moveTo( halfThickness, soundValue);
				}
				
				//WORK THROUGH REST OF VALUES
				for( var i:uint=1; i<256; i++)
				{
					soundValue = -ba.readFloat()*plotYAxis + plotYAxis;

					graphics.lineTo( Math.floor( plotXStep * i + halfThickness ), soundValue);
				}
				
				if( _drawMode == DRAW_FILLED )
				{
					graphics.lineTo( _width - halfThickness, plotYAxis )
					
					graphics.endFill();
				}
			}
			else
			{
				graphics.lineTo( _width, plotYAxis);
			}
		}
/**
 * The colour to use in drawing the wave
 */		
		public function get waveColour():uint
		{
			return _waveColour;
		}
/**
 * @private
 */
		public function set waveColour( theColour:uint ):void
		{
			_waveColour = theColour;
		}
/**
 * The thickness of the wave line in pixels
 */
		public function get waveThickness():uint
		{
			return _waveThickness;
		}
/**
 * @private
 */
		public function set waveThickness( thickness:uint ):void
		{
			_waveThickness = thickness;
		}
/**
 * The width in pixels of the wave line
 */
		override public function get width():Number
		{
			return _width;
		}
/**
 * @private
 */
		override public function set width( value:Number ):void
		{
			_width = value;
		}
/**
 * The height in pixels into which the wave amplitude should be drawn
 */
		override public function get height():Number
		{
			return _height;
		}
/**
 * @private
 */
		override public function set height( value:Number ):void
		{
			_height = value;
		}
/**
 * <p>
 * The draw mode. Can be one of:<br/>
 * DRAW_LINE_ONLY<br/>
 * DRAW_FILLED
 * </p>
 * @default DRAW_LINE_ONLY
 */
		public function get drawMode():String
		{
			return _drawMode;
		}
/**
 * @private
 */
		public function set drawMode( value:String ):void
		{
			_drawMode = value;
		}
	}
}